#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sqlite3.h>

#define MAX_buf_SIZE 1024
#define DATABASE_NAME "my.db"

typedef struct {
    int id;
    char username[50];
    char password[50];
} User;

void handle_error(char *error_msg) {
    perror(error_msg);
    exit(EXIT_FAILURE);
}

int login(sqlite3_stmt *db, char *username, char *password)
{
    char sql[MAX_buf_SIZE];
    snprintf(sql, sizeof(sql), "SELECT * FROM users WHERE username='%s' AND password='%s';", username, password);

    sqlite3_stmt *stmt;
    if (sqlite3_stmt_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
    {
        handle_error("Failed to prepare statement");
    }

    int result = 0;
    if (sqlite3_stmt_step(stmt) == SQLITE_ROW)
    {
        result = sqlite3_stmt_column_int(stmt, 0);
    }

    sqlite3_stmt_finalize(stmt);
    return result;
}

int register_user(sqlite3_stmt *db, char *username, char *password)
{
    char sql[MAX_buf_SIZE];
    snprintf(sql, sizeof(sql), "INSERT INTO users (username, password) VALUES('%s', '%s');", username, password);

    sqlite3_stmt *stmt;
    if (sqlite3_stmt_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
    {
        handle_error("Failed to prepare statement");
    }

    int result = sqlite3_stmt_step(stmt);

    sqlite3_stmt_finalize(stmt);
    return result;
}

int change_password(sqlite3_stmt *db, char *username, char *old_password, char *new_password)
{
    char sql[MAX_buf_SIZE];
    snprintf(sql, sizeof(sql), "UPDATE users SET password='%s' WHERE username='%s' AND password='%s';", new_password, username, old_password);

    sqlite3_stmt *stmt;
    if (sqlite3_stmt_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
    {
        handle_error("Failed to prepare statement");
    }

    int result = sqlite3_stmt_step(stmt);

    sqlite3_stmt_finalize(stmt);
    return result;
}

int delete_user(sqlite3_stmt *db, char *username)
{
    char sql[MAX_buf_SIZE];
    snprintf(sql, sizeof(sql), "DELETE FROM users WHERE username='%s';", username);

    sqlite3_stmt *stmt;
    if (sqlite3_stmt_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
    {
        handle_error("Failed to prepare statement");
    }

    int result = sqlite3_stmt_step(stmt);

    sqlite3_stmt_finalize(stmt);
    return result;
}

int main() {
    // 创建套接字socket
    int sfd;
    if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        handle_error("Failed to create socket");
    }

    // 设置服务器地址
    struct sockaddr_in srv_addr;
    memset(&srv_addr, 0, sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_port = htons(8080);
    srv_addr.sin_addr.s_addr = INADDR_ANY;

    // 绑定socket和地址
    if (bind(sfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) == -1)
    {
        handle_error("Failed to bind");
    }

    // 监听连接
    if (listen(sfd, 5) == -1)
    {
        handle_error("Failed to listen");
    }

    // 连接数据库
    sqlite3 *db;
    if (sqlite3_open(DATABASE_NAME, &db) != SQLITE_OK)
    {
        handle_error("Failed to connect to database");
    }

    // 创建用户表
    char *create_table_sql = "CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, password TEXT NOT NULL);";
    if (sqlite3_exec(db, create_table_sql, NULL, NULL, NULL) != SQLITE_OK)
    {
        handle_error("Failed to create table");
    }

    // 接受并处理连接
    int cfd;
    struct sockaddr_in client_address;
    socklen_t address_length = sizeof(client_address);

    while ((cfd = accept(sfd, (struct sockaddr *)&client_address, &address_length))) {
        char buf[MAX_buf_SIZE] = {0};
        if (recv(cfd, buf, MAX_buf_SIZE, 0) == -1)
        {
            handle_error("Failed to receive data");
        }

        // 解析请求
        char *request = strtok(buf, "|");
        char *username = strtok(NULL, "|");
        char *password = strtok(NULL, "|");

        // 处理请求
        int result;
        if (strcmp(request, "login") == 0)
        {
            result = login(db, username, password);
        }
        else if (strcmp(request, "register") == 0)
        {
            result = register_user(db, username, password);
        }
        else if (strcmp(request, "change_password") == 0)
        {
            char *new_password = strtok(NULL, "|");
            result = change_password(db, username, password, new_password);
        }
        else if (strcmp(request, "delete_user") == 0)
        {
            result = delete_user(db, username);
        }
        else
        {
            result = 0;  // 未知请求
        }

        // 发送响应
        char response[MAX_buf_SIZE] = {0};
        snprintf(response, sizeof(response), "%d", result);
        if (send(cfd, response, strlen(response), 0) == -1)
        {
            handle_error("Failed to send data");
        }

        close(cfd);
    }

    sqlite3_close(db);
    close(sfd);

    return 0;
}

